package com.hskn.hss.module.tlcostoperate.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hskn.hss.core.annotation.DataScope;
import com.hskn.hss.core.annotation.SysLog;
import com.hskn.hss.core.domain.BaseEntity;
import com.hskn.hss.core.enums.BusinessType;
import com.hskn.hss.core.utils.file.FileTypeUtils;
import com.hskn.hss.core.utils.poi.ExcelUtil;
import com.hskn.hss.entity.AjaxResult;
import com.hskn.hss.exception.ExcelReaderDataException;
import com.hskn.hss.exception.HssException;
import com.hskn.hss.module.alarmashbin.service.IAlarmAshbinService;
import com.hskn.hss.module.common.ienum.ExcelTypeEnum;
import com.hskn.hss.module.costdictitem.entity.CostDictItem;
import com.hskn.hss.module.costdictitem.service.ICostDictItemService;
import com.hskn.hss.module.depart.entity.SysDepart;
import com.hskn.hss.module.depart.mapper.SysDepartMapper;
import com.hskn.hss.module.depart.service.ISysDepartService;
import com.hskn.hss.module.tlcarmanufacturer.mapper.TlCarManufacturerMapper;
import com.hskn.hss.module.tlcompany.mapper.TlCompanyMapper;
import com.hskn.hss.module.tlcostdateil.entity.TlCostDateil;
import com.hskn.hss.module.tlcostoperate.bo.TlCostOperateForElectricBO;
import com.hskn.hss.module.tlcostoperate.bo.TlCostOperateForOtherBO;
import com.hskn.hss.module.tlcostoperate.bo.TlCostOperateForWaterBO;
import com.hskn.hss.module.tlcostoperate.entity.TlCostOperate;
import com.hskn.hss.module.tlcostoperate.iEnum.TlCostOperateTypeEnum;
import com.hskn.hss.module.tlcostoperate.mapper.TlCostOperateMapper;
import com.hskn.hss.module.tlcostoperate.service.ITlCostOperateService;
import com.hskn.hss.module.tlcostoperate.to.CostOperateCfgListTO;
import com.hskn.hss.module.tlcostoperate.to.CostOperateExcelReaderTO;
import com.hskn.hss.module.tlcostoperate.to.ExcelExportTemplateTO;
import com.hskn.hss.module.tlcostoperate.vo.*;
import com.hskn.hss.module.tlprovider.entity.TlProvider;
import com.hskn.hss.module.tlprovider.mapper.TlProviderMapper;
import com.hskn.hss.module.user.entity.User;
import com.hskn.hss.module.user.mapper.UserMapper;
import com.hskn.hss.module.tlcostoperate.vo.CostOperateCfgExcelOutVO;
import com.hskn.hss.module.tlcostoperate.vo.TlCostOperateForElectricVO;
import com.hskn.hss.module.tlcostoperate.vo.TlCostOperateForOtherVO;
import com.hskn.hss.module.tlcostoperate.vo.TlCostOperateForWaterVO;
import com.hskn.hss.module.tlemployee.mapper.TlEmployeeMapper;
import com.hskn.hss.to.ForIdsTO;
import com.hskn.hss.utils.GroupingByUtils;
import com.hskn.hss.utils.Tools;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author hskn
 * @since 2021-05-20
 */
@Slf4j
@RestController
@RequestMapping("/hss/tlcostoperate")
@Api(tags = {"-tl_costoperate"}, description = "运营杂费接口")
public class TlCostOperateController {

    @Autowired
    ITlCostOperateService tlCostOperateService;
    @Autowired
    private ISysDepartService departService;
    @Autowired
    private ICostDictItemService costDictItemService;
    @Resource
    UserMapper userMapper;
    @Resource
    TlProviderMapper tlProviderMapper;

    @SysLog(businessType = BusinessType.INSERT, tableName = "tl_cost_operate", bean = TlCostOperate.class, beanMapper = TlCostOperateMapper.class,
            names = "waterdept", twoBeanMapper = SysDepartMapper.class, twoNames = "departName", twoTableName = "sys_depart")
    @RequestMapping(value = "insert", method = RequestMethod.POST)
    public AjaxResult<Object> insert(HttpServletRequest request) {
        try {
            JSONObject params = JSON.parseObject(Tools.getBody(request));
            return tlCostOperateService.insert(params);
        } catch (HssException e) {
            e.printStackTrace();
            log.error("报错ERROR", e);
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @SysLog(businessType = BusinessType.UPDATE, tableName = "tl_cost_operate", idKey = "id", bean = TlCostOperate.class, beanMapper = TlCostOperateMapper.class,
            names = "waterdept", twoBeanMapper = SysDepartMapper.class, twoNames = "departName", twoTableName = "sys_depart")
    @RequestMapping(value = "update", method = RequestMethod.POST)
    public AjaxResult<Object> update(HttpServletRequest request) {
        try {
            JSONObject params = JSON.parseObject(Tools.getBody(request));
            return tlCostOperateService.update(params);
        } catch (HssException e) {
            e.printStackTrace();
            log.error("报错ERROR", e);
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @SysLog(businessType = BusinessType.DELETE, tableName = "tl_cost_operate", idKey = "ids", bean = TlCostOperate.class, beanMapper = TlCostOperateMapper.class,
            names = "waterdept", twoBeanMapper = SysDepartMapper.class, twoNames = "departName", twoTableName = "sys_depart")
    @RequestMapping(value = "deletebyid", method = RequestMethod.POST)
    public AjaxResult<Object> deletebyid(@RequestBody @Validated ForIdsTO forIdsTO) {
        try {
            return tlCostOperateService.deletebyid(forIdsTO);
        } catch (HssException e) {
            e.printStackTrace();
            log.error("报错ERROR", e);
            return AjaxResult.fail("删除失败，请稍后再试");
        }
    }


    @RequestMapping(value = "getDetail", method = RequestMethod.POST)
    public AjaxResult<Object> getDetail(HttpServletRequest request) {
        JSONObject params = JSON.parseObject(Tools.getBody(request));
        TlCostOperate tlCostOperate = null;
        try {
            tlCostOperate = tlCostOperateService.getDetail(params);
        } catch (HssException e) {
            e.printStackTrace();
            log.error("报错ERROR", e);
            return AjaxResult.fail("获取信息失败，请稍后再试");
        }
        return AjaxResult.success(tlCostOperate);

    }

    @RequestMapping(value = "getList", method = RequestMethod.POST)
    public AjaxResult<Object> getList(HttpServletRequest request) {
        JSONObject params = JSON.parseObject(Tools.getBody(request));
        try {
            BaseEntity entity = new BaseEntity();
            JSONObject json = tlCostOperateService.getList(entity, params);
            return AjaxResult.success(json);
        } catch (HssException e) {
            e.printStackTrace();
            log.error("报错ERROR", e);
            return AjaxResult.fail("获取信息失败，请稍后再试");
        }

    }

    /**
     * 运营费导入接口
     *
     * @param request
     * @return
     */
//    @SysLog(businessType = BusinessType.INSERT, tableName = "tl_cost_operate", bean = TlCostOperate.class, beanMapper = TlCostOperateMapper.class, names = "id")
    @ApiOperation(value = "运营费导入接口", notes = "运营费导入")
    @ApiResponses({
            @ApiResponse(code = 200, message = "ok")
    })
    @PostMapping("excelReader")
    public AjaxResult excelReader(HttpServletRequest request, @ModelAttribute @Validated CostOperateExcelReaderTO excelReaderTo) {
        try {
            MultipartFile file = excelReaderTo.getFiles();
            String types = excelReaderTo.getTypes();
            if (Arrays.stream(ExcelTypeEnum.values())
                    .noneMatch(s -> s.getName().equals(FileTypeUtils.getFileType(file.getOriginalFilename().toLowerCase())))) {
                return AjaxResult.fail("导入文件格式错误");
            }
            InputStream inputStream = new BufferedInputStream(file.getInputStream());
            List<TlCostOperate> costOperateList = new ArrayList<>();
            if (Arrays.stream(TlCostOperateTypeEnum.values())
                    .anyMatch(s -> s.getName().equals(types))) {
                if (types.equals("水费")) {
                    ExcelUtil<TlCostOperateForWaterBO> util = new ExcelUtil<TlCostOperateForWaterBO>(TlCostOperateForWaterBO.class);
                    List<TlCostOperateForWaterBO> costOperateForWaterBOList = util.importExcel(inputStream);
                    costOperateList = JSONObject.parseArray(JSONObject.toJSONString(costOperateForWaterBOList), TlCostOperate.class);
                } else if (types.equals("电费")) {
                    ExcelUtil<TlCostOperateForElectricBO> util = new ExcelUtil<TlCostOperateForElectricBO>(TlCostOperateForElectricBO.class);
                    List<TlCostOperateForElectricBO> costOperateForElectricBOList = util.importExcel(inputStream);
                    costOperateList = JSONObject.parseArray(JSONObject.toJSONString(costOperateForElectricBOList), TlCostOperate.class);
                } else if (types.equals("杂费")) {
                    ExcelUtil<TlCostOperateForOtherBO> util = new ExcelUtil<TlCostOperateForOtherBO>(TlCostOperateForOtherBO.class);
                    List<TlCostOperateForOtherBO> costOperateForOtherBOList = util.importExcel(inputStream);
                    costOperateList = JSONObject.parseArray(JSONObject.toJSONString(costOperateForOtherBOList), TlCostOperate.class);
                }
            } else {
                return AjaxResult.fail("类型错误");
            }
            if (costOperateList.isEmpty()) {
                return AjaxResult.fail("导入内容为空");
            }
            tlCostOperateService.excelReader(costOperateList,types);
            if ( tlCostOperateService.saveBatch(costOperateList)) {
                return AjaxResult.success();
            } else {
                return AjaxResult.fail("导入失败");
            }
        } catch (ExcelReaderDataException e) {
            return AjaxResult.fail(e.getMessage());
        } catch (Exception exception) {
            exception.printStackTrace();
            return AjaxResult.fail();
        }

    }

    @ApiOperation(value = "运营费导出接口", notes = "运营费导出")
    @ApiResponses({
            @ApiResponse(code = 200, message = "ok", response = CostOperateCfgExcelOutVO.class)
    })
    @PostMapping("excelExport")
    @DataScope(deptAlias = "waterdept", userAlias = "createby")
    public com.hskn.hss.core.domain.AjaxResult excelExport(HttpServletRequest request, @RequestBody CostOperateCfgListTO costOperateListTo) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            if((costOperateListTo.getIds()!=null&&costOperateListTo.getIds().isEmpty())){
                return com.hskn.hss.core.domain.AjaxResult.error("请选择至少一条数据导出");
            }
            //查询数据
            List<TlCostOperate> costOperateList = tlCostOperateService.getTlCostOperate(costOperateListTo, format);
            List<User> userList = userMapper.selectList(new QueryWrapper<>());

            List<String> ids = costOperateList.stream().map(TlCostOperate::getServicevendor).distinct().collect(Collectors.toList());
            List<TlProvider> tlProviderList =  tlProviderMapper.selectBatchIds(ids);
            for (TlProvider tlProvider : tlProviderList) {
                for (TlCostOperate tlCostOperate : costOperateList) {
                    if(tlCostOperate.getServicevendor().equals(tlProvider.getId())){
                        tlCostOperate.setServicevendor(tlProvider.getProvidername());
                    }
                }
            }

            //工具类实例化
            ExcelUtil<CostOperateCfgExcelOutVO> util = new ExcelUtil<CostOperateCfgExcelOutVO>(CostOperateCfgExcelOutVO.class);
            ExcelUtil<CostOperateCfgEleExcelOutVO> util1 = new ExcelUtil<CostOperateCfgEleExcelOutVO>(CostOperateCfgEleExcelOutVO.class);
            ExcelUtil<CostOperateCfgWaterExcelOutVO> util2 = new ExcelUtil<CostOperateCfgWaterExcelOutVO>(CostOperateCfgWaterExcelOutVO.class);
            //数据载体转换
            List<CostOperateCfgExcelOutVO> costOperateExcelOutVOList = JSONObject.parseArray(JSONObject.toJSONString(costOperateList), CostOperateCfgExcelOutVO.class);
            List<CostOperateCfgEleExcelOutVO> costOperateCfgEleExcelOutVOS = new ArrayList<>();
            List<CostOperateCfgWaterExcelOutVO> costOperateCfgWaterExcelOutVOS = new ArrayList<>();
            //构造结果集
            Map<String, SysDepart> departMap = departService.getDepartMap(new QueryWrapper<>());
            Map<String, CostDictItem> costDictItemMap = costDictItemService.getCostDictItemMap(new QueryWrapper<>());
            Map<String, User> userMap = GroupingByUtils.getGroupingForMapEntity(userList, User::getUid, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));


            for (CostOperateCfgExcelOutVO costOperateExcelOutVO : costOperateExcelOutVOList) {
                if (departMap.containsKey(costOperateExcelOutVO.getWaterdept())) {
                    costOperateExcelOutVO.setWaterdeptName(departMap.get(costOperateExcelOutVO.getWaterdept()).getDepartName());
                }
                if (costDictItemMap.containsKey(costOperateExcelOutVO.getCosttypeitem())) {
                    costOperateExcelOutVO.setCosttypeitemName(costDictItemMap.get(costOperateExcelOutVO.getCosttypeitem()).getCostname());
                }
                if (userMap.containsKey(costOperateExcelOutVO.getPayperson())) {
                    costOperateExcelOutVO.setPaypersonName(userMap.get(costOperateExcelOutVO.getPayperson()).getName());
                }
            }
            costOperateExcelOutVOList = costOperateExcelOutVOList.stream().sorted(Comparator.comparing(CostOperateCfgExcelOutVO::getPaytime).reversed()).collect(Collectors.toList());
            //            导出
            if(costOperateListTo.getTypes().equals("水费")){
                for (CostOperateCfgExcelOutVO costOperateCfgExcelOutVO : costOperateExcelOutVOList) {
                    CostOperateCfgWaterExcelOutVO water = new CostOperateCfgWaterExcelOutVO();
                    BeanUtils.copyProperties(costOperateCfgExcelOutVO,water);
                    costOperateCfgWaterExcelOutVOS.add(water);
                }
                return util2.exportExcel(costOperateCfgWaterExcelOutVOS, "水费");
            } else if(costOperateListTo.getTypes().equals("电费")){
                for (CostOperateCfgExcelOutVO costOperateCfgExcelOutVO : costOperateExcelOutVOList) {
                    CostOperateCfgEleExcelOutVO ele = new CostOperateCfgEleExcelOutVO();
                    BeanUtils.copyProperties(costOperateCfgExcelOutVO,ele);
                    costOperateCfgEleExcelOutVOS.add(ele);
                }
                return util1.exportExcel(costOperateCfgEleExcelOutVOS, "电费");
            }else{
                return util.exportExcel(costOperateExcelOutVOList, "杂费");
            }

        } catch (Exception e) {
            e.printStackTrace();
            return com.hskn.hss.core.domain.AjaxResult.error();
        }
    }

    @ApiOperation(value = "运营费导出模板接口", notes = "运营费模板导出")
    @ApiResponses({
            @ApiResponse(code = 200, message = "ok", response = CostOperateCfgExcelOutVO.class)
    })
    @PostMapping("excelExportTemplate")
    public com.hskn.hss.core.domain.AjaxResult excelExportTemplate(HttpServletRequest request, @RequestBody ExcelExportTemplateTO excelExportTemplateTO) {
        try {
            if (excelExportTemplateTO.getTypes().equals("电费")) {
                //工具类实例化
                ExcelUtil<TlCostOperateForElectricVO> util = new ExcelUtil<TlCostOperateForElectricVO>(TlCostOperateForElectricVO.class);
                //数据载体转换
                List<TlCostOperateForElectricVO> tlCostOperateForElectricVOList = new ArrayList<>();
                //导出
                return util.exportExcel(tlCostOperateForElectricVOList, "运营模板");
            } else if (excelExportTemplateTO.getTypes().equals("水费")) {
                //工具类实例化
                ExcelUtil<TlCostOperateForWaterVO> util = new ExcelUtil<TlCostOperateForWaterVO>(TlCostOperateForWaterVO.class);
                //数据载体转换
                List<TlCostOperateForWaterVO> tlCostOperateForWaterVOList = new ArrayList<>();
                //导出
                return util.exportExcel(tlCostOperateForWaterVOList, "运营模板");
            } else if (excelExportTemplateTO.getTypes().equals("杂费")) {
                //工具类实例化
                ExcelUtil<TlCostOperateForOtherVO> util = new ExcelUtil<TlCostOperateForOtherVO>(TlCostOperateForOtherVO.class);
                //数据载体转换
                List<TlCostOperateForOtherVO> tlCostOperateForOtherVOList = new ArrayList<>();
                //导出
                return util.exportExcel(tlCostOperateForOtherVOList, "运营模板");
            } else {
                return com.hskn.hss.core.domain.AjaxResult.error("类型不存在");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return com.hskn.hss.core.domain.AjaxResult.error();
        }

    }
}

